﻿// Property Distribution Aizu - 0118.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <iostream>


using namespace std;

//https://vjudge.csgrandeur.cn/problem/Aizu-0118
/*
問題：
田中先生去世后留下了一个HW平方米的果园。果园被分成了H×W个方块，每个方块上种植着苹果、柿子和橘子。
田中先生在遗嘱中留下了以下要求：

尽可能将果园按照方块单位划分给尽可能多的亲属。但是，如果某个方块的东西南北四个方向有相邻的方块都种植着相同类型的果树，
则认为这些方块是一个大的连续区域。

例如，对于如下的3×10的方块（'リ'表示苹果，'カ'表示柿子，'ミ'表示橘子）：

消除相邻方块之间的边界后，如下所示：

最终，可以将其分成10个方块，即10个人。

您需要在看不到方块边界的情况下完成分配，您的任务是根据果园地图确定分配的方块数量。

请编写一个程序，根据果园的地图输出可以进行分配的亲属人数。

输入：
输入包含多个数据集。每个数据集以包含用空格分隔的H和W（H，W ≤ 100）的行开始，然后是H行由H×W个字符组成的字符串。
该字符串只包含三个字符：'@'表示苹果，'#'表示柿子，'*'表示橘子。

输入以两行的两个零结束。数据集的数量不超过20个。

输出：
对于每个数据集，请输出可以接受分配的亲属人数。

10 10
####*****@
@#@@@@#*#*
@##***@@@*
#****#*@**
##@*#@@*##
*@@@@*@@@#
***#@*@##*
*@@@*@@##@
*@*#*@##**
@****#@@#@
10 10
####*****@
@#@@@@#*#*
@##***@@@*
#****#*@**
##@*#@@*##
*@@@@*@@@#
***#@*@##*
*@@@*@@##@
*@*#*@##**
@****#@@#@
0 0

33
*/

const int N = 150;
char gra[N][N];
int h, w;
const int addx[] = { 1,-1,0,0 };
const int addy[] = { 0,0,1,-1 };


void dfs(int x,int y,char flag) {
	if (gra[x][y] == flag) {
		gra[x][y] = '.';
	}

	for (int i = 0; i < 4; i++) {
		int newx = x + addx[i];
		int newy = y + addy[i];

		if (newx >= 0 && newx < h && newy >= 0 && newy < w && gra[newx][newy] == flag) {
			dfs(newx, newy, flag);
		}
	}

	return;
}


void solve() {
	int ans = 0;
	for (int i = 0; i < h; i++) {
		for (int j = 0; j < w; j++) {
			if (gra[i][j] == '#' || '*' == gra[i][j] || '@' == gra[i][j]) {
				dfs(i, j, gra[i][j]);
				ans++;
			}
		}
	}

	cout << ans << endl;
	return;
}

int main()
{
	while (cin >> h >> w) {
		if (h == 0 || w == 0) break;
		for (int i = 0; i < h; i++) {
			for (int j = 0; j < w; j++) {
				cin >> gra[i][j];
			}
		}

		solve();
	}
	
	return 0;
}
 